import wx
from socket import *
import threading
from concurrent.futures import ThreadPoolExecutor


class Server(wx.Frame):
    def __init__(self):
        # 服务器是否开启 / 服务器接口信息 / 保存所有客户端
        self.isOn = False
        self.server_socket = socket()
        # 绑定IP地址
        self.server_socket.bind(("0.0.0.0",8999))
        self.server_socket.listen(5)
        # 保存所有客户端
        self.client_thread_dict = {}
        # 创建线程池
        self.pool = ThreadPoolExecutor(max_workers=10)

        # 界面布局
        super().__init__(None,title="多人聊天室",pos=(0,50),size=(450,600))
        self.pl = wx.Panel(self)

        ## 创建按钮 启动服务器 / 保存聊天记录
        self.btn_start = wx.Button(self.pl,label="启动服务器",pos=(10,10),size=(200,40))
        self.btn_save = wx.Button(self.pl,label="保存聊天记录",pos=(220,10),size=(200,40))

        ## 聊天窗口
        self.text = wx.TextCtrl(self.pl, size=(400, 400), pos=(10, 60), style=wx.TE_READONLY | wx.TE_MULTILINE)

        ## 绑定按钮
        self.Bind(wx.EVT_BUTTON,self.StartServer,self.btn_start)
        self.Bind(wx.EVT_BUTTON, self.SaveContent, self.btn_save)

    def StartServer(self,event):
        print("启动服务器")
        # 是否能够启动
        if self.isOn == False:
            self.isOn = True
            # 直接使用进程会使程序只执行进程对应操作
            # 因此使用一个线程启动服务器
            # 创建线程
            main_thread = threading.Thread(target=self.main_thread_func)
            # 设置为守护线程
            main_thread.daemon = True
             # 启动线程
            main_thread.start()

    def SaveContent(self,event):
        record = self.text.GetValue()
        with open('record.log','a+',encoding="utf-8") as f:
            f.write(record)

    def main_thread_func(self):
        while self.isOn:
            client_socket,client_addr = self.server_socket.accept()
            print(client_addr)

            # 接收用户名
            client_name = client_socket.recv(1024).decode('utf8')
            # 建立连接用户的相关信息
            client_thread = ClientThread(client_socket,client_name,self)
            print(client_thread.isOn)
            # 保存用户
            self.client_thread_dict[client_name] = client_thread
            # 保存信息
            self.pool.submit(client_thread.run)
            self.send(f"【服务器通知】欢迎{client_name}加入服务器！")

    # 服务器群发消息
    def send(self,text):
        for client in self.client_thread_dict.values():
            if client.isOn:
                client.client_socket.send(text.encode('utf8'))

class ClientThread(threading.Thread):
    def __init__(self,socket,name,server):
        threading.Thread.__init__(self)
        self.client_socket = socket
        self.client_name = name
        self.server = server
        self.isOn = True

    def run(self):
        while self.isOn:
            text = self.client_socket.recv(1024).decode('utf8')
            if text == "断开连接":
                self.isOn = False
                self.server.send(f"【服务器消息】{self.client_name}离开了服务器")
            else:
                self.server.send(f"【{self.client_name}】{text}")

        self.client_socket.close()



if __name__ == "__main__":
    app = wx.App()
    Server = Server()
    Server.Show()
    app.MainLoop()